﻿using System;

namespace TCPtester
{
    using System;
    using System.Collections.Generic;
    using System.Net;
    using System.Text;
    using SharpPcap;
    using SharpPcap.LibPcap;

  
        /// <summary>
        /// A sample showing how to use the Address Resolution Protocol (ARP)
        /// with the SharpPcap library.
        /// </summary>
        public class ArpTest
        {
            public static void Main(string[] args)
            {
                // Print SharpPcap version

                // Retrieve the device list
                var devices = LibPcapLiveDeviceList.Instance;

                // If no devices were found print an error
                if (devices.Count < 1)
                {
                    Console.WriteLine("No devices were found on this machine");
                    return;
                }

                Console.WriteLine("The following devices are available on this machine:");
                Console.WriteLine("----------------------------------------------------");
                Console.WriteLine();

                int i = 0;

                // Print out the available devices
                foreach (var dev in devices)
                {
                    Console.WriteLine("{0}) {1} {2}", i, dev.Name, dev.Description,dev.ToString());
                    i++;
                }

            Console.Write("Please choose a device to capture:");
            while (true ) 
            {
                int.TryParse(Console.ReadLine(),out i);
                if (i == 99) 
                { break; }
                using var device = devices[i];

                //Register our handler function to the 'packet arrival' event
                device.OnPacketArrival +=
                    new PacketArrivalEventHandler(device_OnPacketArrival);

                // Open the device for capturing
                int readTimeoutMilliseconds = 1000;
                device.Open(DeviceModes.Promiscuous, readTimeoutMilliseconds);

                //tcpdump filter to capture only TCP/IP packets
                string filter = "ip and tcp";
                device.Filter = filter;

                Console.WriteLine();
                Console.WriteLine
                    ("-- The following tcpdump filter will be applied: \"{0}\"",
                    filter);
                Console.WriteLine
                    ("-- Listening on {0}, hit 'Ctrl-C' to exit...",
                    device.Description);

                // Start capture 'INFINTE' number of packets
                device.Capture();
            }

        }
        static IPAddress huobiChiIp = IPAddress.Parse("47.93.57.64");
        private static void device_OnPacketArrival(object sender, PacketCapture e)
        {
            var time = e.Header.Timeval.Date;
            var len = e.Data.Length;
            var rawPacket = e.GetPacket();

            var packet = PacketDotNet.Packet.ParsePacket(rawPacket.LinkLayerType, rawPacket.Data);

            var tcpPacket = packet.Extract<PacketDotNet.TcpPacket>();
            if (tcpPacket != null)
            {

                var ipPacket = (PacketDotNet.IPPacket)tcpPacket.ParentPacket;
                System.Net.IPAddress srcIp = ipPacket.SourceAddress;
                System.Net.IPAddress dstIp = ipPacket.DestinationAddress;
                int srcPort = tcpPacket.SourcePort;
                int dstPort = tcpPacket.DestinationPort;
                
                if (srcIp.ToString() == huobiChiIp.ToString() || dstIp.ToString() == huobiChiIp.ToString()) 
                {
                    Console.WriteLine("{0}:{1}:{2},{3} Len={4} {5}:{6} -> {7}:{8}",
                        time.Hour, time.Minute, time.Second, time.Millisecond, len,
                        srcIp, srcPort, dstIp, dstPort);

                    Console.WriteLine(packet.PayloadData.Bytes2String(Encoding.ASCII));
                    Console.WriteLine("---------------------------------------------------------------------------------------");
                    Console.WriteLine(packet.Bytes.Bytes2String(Encoding.ASCII));
                    Console.WriteLine("---------------------------------------------------------------------------------------");
                    Console.WriteLine(packet.HeaderData.Bytes2String(Encoding.ASCII));
                    Console.WriteLine("---------------------------------------------------------------------------------------");
                    Console.WriteLine(packet.PrintHex());
                    Console.WriteLine("---------------------------------------------------------------------------------------");
                }

            }
        }


    }

    public static class ByteExtension
    {
        public static string Utf8String(this byte[] bytes)
        {
            if (bytes == null || bytes.Length == 0) return "";
            var str = System.Text.Encoding.UTF8.GetString(bytes);
            return str;

        }



        public static string Bytes2String(this byte[] bytes, Encoding coder)
        {
            if (bytes == null || bytes.Length == 0) return "";
            var str = coder.GetString(bytes);
            return str;

        }

        public static byte[] Utf8Bytes(this string str)
        {
            if (string.IsNullOrEmpty(str)) return null;

            var bytes = System.Text.Encoding.UTF8.GetBytes(str);
            return bytes;

        }

        public static byte[] String2Bytes(this string str, Encoding coder)
        {
            if (string.IsNullOrEmpty(str)) return null;

            var bytes = coder.GetBytes(str);
            return bytes;

        }
    }

}
